import _ from 'lodash';
import moment from 'moment';
import React, { useEffect, useImperativeHandle, forwardRef } from 'react';
import { Space, Select } from 'antd';
import { useTablePipeline, features } from 'ali-react-table';

import { TRDefault } from '#/components';
import { HttpCode } from '#/utils/contacts.js';
import { useTRState } from '#/utils/trHooks.jsx';
import { PageLoading } from '@/components/index.js';
import { exportGroup } from '@/utils/fileExport.js';
import { TjChart, TjCollapse, TjTable } from '@/pages/ETrade/components';

import styles from './index.less';
import { Dimension, Board, FilterColumns } from '../components';
import { removeEmptyRowData, getTableData, flattenDeep } from '../tool';
import { queryReanalyzeDataData, getDynamicColumns } from '../services.js';
import { CODE1, columns, chartsMap, SELECT_DATA, seriseMap, yAxisMap } from '../helper';

const Main = forwardRef(({ formValue, menuCode }, ref) => {
  const [openKeys, onChangeOpenKeys] = React.useState([1]);
  const [state, setState] = useTRState({
    charts: {},
    order: [],
    filters: [],
    filterOptions: [],
    columnsRes: [],
    tableData: [],
    selectColumns: [],
    exportTable: [],
    loading: true,
    sorts: [],
  });

  const {
    filterOptions,
    order,
    charts,
    columnsRes,
    tableData,
    selectColumns,
    exportTable,
    loading,
    sorts,
  } = state;

  useImperativeHandle(ref, () => ({
    onFetch: () => {
      onFetch([SELECT_DATA[0], SELECT_DATA[1]], formValue);
    },
    onExport,
  }));

  useEffect(() => {
    const filters = Array.from({ length: order.length - 1 }, () => 0);
    onChangeFilters(filters);
    setState({
      filters,
    });
  }, [tableData]);

  //请求表格数据
  const onFetch = async (order, params) => {
    const { date, point, provinceId, unit, tag } = params;
    setState({
      loading: true,
      tableData: [],
      order,
    });

    const startDate = moment(date[0]).format('YYYY-MM-DD');
    const endDate = moment(date[1]).format('YYYY-MM-DD');

    const param = {
      provinceId,
      stationIds: unit,
      pointNum: point,
      startDate,
      endDate,
      tag,
    };

    const res = await Promise.all([
      queryReanalyzeDataData({ order, param }),
      getDynamicColumns({
        regionCode: provinceId,
        menuCode,
      }),
    ]);
    if (res[0].statusCode === HttpCode.SUCCESS && res[1].statusCode === HttpCode.SUCCESS) {
      const selectColumns = flattenDeep(res[1].data);
      const { tableData, exportTable } = getTableData(res[0].data, order, point);

      setState({
        tableData,
        exportTable,
        selectColumns,
        columnsRes: res[1]?.data || [],
      });
    }
    setState({
      loading: false,
    });
  };

  const onExport = async () => {
    if (!exportTable.length) return;
    const { provinceName, date } = formValue;

    const _columns = _.flatMapDeep(
      columns.map((x) => {
        if (!x?.children?.length) {
          return {
            header: x.name,
            key: x.code,
          };
        }

        return x?.children?.map((y) => ({
          header: y.name,
          key: y.code,
        }));
      }),
    );
    const fileName = `${provinceName}${date[0].split('-').join('')}-${date[1].split('-').join('')}`;

    exportGroup(tableData, _columns, fileName);
  };

  const onChangeFilters = (filters) => {
    // 聚合维度处理
    let _options = [];
    const len = filters.length;
    const fn = (list, lv) => {
      const dataI = filters[lv];
      const { children = [] } = list[dataI] || {};
      if (lv === len) {
        _options[lv] = list;
      } else {
        _options[lv] = list.map((x, idx) => ({ label: x[CODE1], value: idx, key: x.key })); //key仅合约维度存在
      }
      lv < len && fn(children, lv + 1);
    };
    // 去掉总合计
    fn(tableData.slice(1), 0);
    // 拿到选项和渲染结果
    const filterOptions = _options.slice(0, -1);
    const charts = _options?.[_options.length - 1];
    setState({
      charts,
      filterOptions,
    });
  };

  const onChangeFilterItem = (lv, idx) => {
    // 当前维度索引更新，子维度索引清0
    let { filters } = state;
    const arrBefore = filters.slice(0, lv + 1);
    const arrAfter = filters.slice(lv + 1).map(() => 0);
    filters = [...arrBefore, ...arrAfter];
    filters[lv] = idx;
    setState({ filters });
    onChangeFilters(filters);
  };

  /**图表配置*/
  const getChartOption = ([title, code], dataSource) => {
    // const code = code.filter((t) => selectColumns.includes(t.replace('_', ''))); //表头筛选同时筛选图表
    const series = code.map((t) => ({ ...seriseMap[t], dataIndex: t }));
    const _data = code.map((t) => t.replace('_', '')); // 同系列名处理

    if (!series.length) return null;
    return {
      grid: { left: 20, top: 25, right: 20, bottom: 25, containLabel: true },
      series,
      dataset: {
        source: dataSource,
        dimensions: [CODE1, ..._data],
      },
      tooltip: {},
      legend: {},
      xAxis: [{ type: 'category' }],
      yAxis: yAxisMap[title],
    };
  };

  const filterColumns = (columns) => {
    const temp = [];
    columns.forEach((t, i) => {
      if (!i) {
        temp.push(t);
        return;
      }
      if (selectColumns.includes(t.code)) {
        temp.push(t);
      } else {
        const children = t.children?.filter((k) => selectColumns.includes(k.code));
        if (children?.length) {
          temp.push({ ...t, children });
        }
      }
    });
    return temp;
  };

  const pipeline = useTablePipeline({ components: {} })
    .input({ dataSource: tableData, columns: filterColumns(columns) })
    .primaryKey('id')
    .use(
      features.treeMode({
        openKeys,
        onChangeOpenKeys,
        indentSize: 20,
        iconIndent: 5,
      }),
    )
    .use(
      features.sort({
        mode: 'single',
        sorts,
        keepDataSource: true,
        onChangeSorts: (params) => {
          setState({ sorts: params });
          if (params.length) {
            const _dataSource = _.cloneDeep(tableData);
            const total = _dataSource[0];
            const spliceData = _dataSource.splice(1);
            const { sortData, noSortData } = removeEmptyRowData(spliceData, params[0].code);

            let newDataSource = [];
            newDataSource = sortData.sort((a, b) => {
              return params[0].order === 'desc'
                ? b[params[0].code] - a[params[0].code]
                : a[params[0].code] - b[params[0].code];
            });

            setState({ tableData: [total, ...newDataSource, ...noSortData] });
            return;
          }

          setState({ tableData: state.tableData });
        },
        highlightColumnWhenActive: true,
      }),
    );

  const _getEchartsData = () => {
    const loopData = Object.entries(chartsMap);
    if (!charts) return <TRDefault type={'empty'} />;
    return (
      <>
        {loopData.map((t, i) => {
          const option = getChartOption(t, charts);
          if (!option) return null;
          return (
            <div key={i} className={styles.chartItem}>
              <div className={styles.chartTitle}>{t[0]}</div>
              <div style={{ flex: 1 }}>
                <TjChart option={option} group="A" />
              </div>
            </div>
          );
        })}
      </>
    );
  };

  if (loading) return <PageLoading />;
  if (!tableData.length) return <TRDefault type="empty" />;

  return (
    <>
      <Board selectColumns={selectColumns} tableData={tableData} />
      <div className={styles.main}>
        <TjCollapse
          left={
            <div className={styles.leftBox}>
              <Dimension
                value={order}
                options={SELECT_DATA}
                onPoly={() => onFetch(order, formValue)}
                onChange={(order) => setState({ order })}
              />
              <FilterColumns
                menuCode={menuCode}
                columns={columnsRes}
                regionCode={formValue?.provinceId}
                fetch={() => onFetch(order, formValue)}
              />
              <TjTable
                style={{ flex: 1, overflowY: 'scroll' }}
                useVirtual="auto"
                defaultColumnWidth={90}
                {...pipeline.getProps()}
              />
            </div>
          }
          right={
            <div className={styles.rightBox}>
              <div className={styles.filter_group}>
                <div className={styles.flex}>
                  <Space size={16}>
                    {filterOptions.map((options, lv) => (
                      <Select
                        key={lv}
                        style={{ minWidth: 140 }}
                        value={state.filters[lv]}
                        options={options}
                        optionFilterProp="label"
                        onChange={(idx) => onChangeFilterItem(lv, idx)}
                        showSearch
                      />
                    ))}
                  </Space>
                </div>
              </div>
              <div className={styles.chart}>{_getEchartsData()}</div>
            </div>
          }
          leftStyles={{ padding: '0 24px 24px 24px' }}
          rightStyles={{ padding: '15px 24px 24px', width: '50%' }}
        />
      </div>
    </>
  );
});

export default Main;
